<?php

namespace App\Models;

use App\Http\Controllers\Wechat\WechatPaySuccessController;
use App\Models\Common\Wechat;
use App\Models\Tools\Data;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * Class WechatPay
 * @package App\Models
 */
class WechatPay
{
    private $we_id;
    private $openid;
    private $type;
    private $outer_id;
    private $num;

    /**
     * WechatPay constructor.
     * @param int $we_id we_id
     * @param string $openid openid
     * @param int $type 消费类型
     * @param string $outer_id 会员id|课程id
     * @param int $num 购买数量（探店服务）
     */
    public function __construct(int $we_id, string $openid, int $type, string $outer_id, int $num = 0)
    {
        $this->we_id = $we_id;
        $this->openid = $openid;
        $this->type = $type;
        $this->outer_id = $outer_id;
        $this->num = $num;
    }

    /**
     * 查询业务价格、名称信息
     * @return bool|mixed
     */
    public function getOrderMessage()
    {
        switch ($this->type){
            case 1: // 购买会员
                $count = DB::table('laifei_vip')->where('we_id','=',$this->we_id)->count();
                if($count){
                    $order_message = DB::table('laifei_sys_vip')
                        ->where('vip_id','=',$this->outer_id)
                        ->select('vip_id as outer_id','price_before as price','title','subtitle')
                        ->first();
                } else {
                    $order_message = DB::table('laifei_sys_vip')
                        ->where('vip_id','=',$this->outer_id)
                        ->select('vip_id as outer_id','price','title','subtitle')
                        ->first();
                }
                break;
            case 2: // 购买课程
                $order_message = DB::table('laifei_sys_course')
                    ->where('course_id','=',$this->outer_id)
                    ->select('course_id as outer_id','price','title','subtitle')
                    ->first();

                // 如果是vip，价格85折
                $is_vip = DB::table('laifei_vip')
                    ->where('we_id','=',$this->we_id)
                    ->where('end_time','>',date('Y-m-d H:i:s'))
                    ->where('vip_id','=',2)
                    ->count();
                if($is_vip){
                    $order_message->price = ceil($order_message->price * 85)/100;
                }
                break;
            case 3: // 购买探店服务
                $order_message = DB::table('explore_channel')
                    ->where('channel_id','=',$this->outer_id)
                    ->select('channel_id as outer_id','price','channel_name as subtitle')
                    ->selectRaw("'达人探店' as title")
                    ->first();
                $order_message->price = ($order_message->price*$this->num)/100;
                break;
            case 4: // 购买霸王餐
                $single_price = DB::table('shop_type')
                    ->where('st_id','=',$this->outer_id)
                    ->value('lottery_price');
                $order_message = [
                    'title' => '霸王餐',
                    'subtitle' => '霸王餐活动',
                    'outer_id' => $this->outer_id,
                    'price' => ($single_price * $this->num)/100,
                ];
                break;
            default:
                return false;
        }
        return json_decode(json_encode($order_message), true);
    }

    /**
     * 创建系统订单
     * @param array $order_message
     * @return array|int
     */
    public function createOrder(array $order_message)
    {

        //查询是否有已购冲突单
        switch ($this->type){
            case 1: // 会员服务
                // 查询当前用户是否有会员订单
                $vip_order = DB::table('laifei_vip')
                    ->where('we_id','=',$this->we_id)
                    ->orderByDesc('vip_id')
                    ->get()
                    ->toArray();
                if(count($vip_order)){ // 如果有会员订单，查询是否过期
                    $vip_order = json_decode(json_encode($vip_order), true);
                    foreach ($vip_order as $key => $value) { // 会员等级由高到低循环
                        if(strtotime($value['end_time']) > strtotime(date('Y-m-d H:i:s'))  // 未过期会员
                            && $this->outer_id < $value['vip_id']){ // 低等级会员
                            return 2; // 未过期且低等级会员，不允许续费
                        }//允许续费当前等级会员/新建会员
                    }// 所有会员订单都已过期，允许任意续费
                }// 不存在会员订单，新建订单

                // 查询是否有未支付完成的订单
                $waiting_order = DB::table('laifei_orders')
                    ->where('we_id','=',$this->we_id)
                    ->where('type','=',1)
                    ->whereIn('status',Data::$laifeiOrderPrepay)
                    ->get()
                    ->toArray();
                $waiting_order = json_decode(json_encode($waiting_order), true);
                // 如果有未支付完成的订单，逐个处理
                if(count($waiting_order)){
                    foreach ($waiting_order as $value){
                        if(self::resolveWaitingOrder($value)){
                            return 4;
                        }
                    }
                }
                break;
            case 2:// 课程服务
                // 查询是否已经购买成功
                $course_count = DB::table('laifei_course')
                    ->where('we_id','=',$this->we_id)
                    ->where('course_id','=',$this->outer_id)
                    ->count();
                if($course_count){
                    return 3;
                }
                // 查询是否有未支付完成的订单
                $waiting_order = DB::table('laifei_orders')
                    ->where('we_id','=',$this->we_id)
                    ->where('outer_id','=',$this->outer_id)
                    ->whereIn('status',Data::$laifeiOrderPrepay)
                    ->get()
                    ->toArray();
                $waiting_order = json_decode(json_encode($waiting_order), true);
                // 如果有未支付完成的订单，逐个处理
                if(count($waiting_order)){
                    foreach ($waiting_order as $value){
                        if(self::resolveWaitingOrder($value)){
                            return 5;
                        }
                    }
                }
                break;
            case 3: // 探店服务
                // 查询当前用户是否有未关闭的相同业务和数量的订单
                $waiting_order = DB::table('laifei_orders')
                    ->where('we_id','=',$this->we_id)
                    ->where('outer_id','=',$this->outer_id)
                    ->where('num','=',$this->num)
                    ->whereIn('status',Data::$laifeiOrderPrepay)
                    ->get()
                    ->toArray();
                $waiting_order = json_decode(json_encode($waiting_order), true);
                // 如果有未支付完成的订单，逐个处理
                if(count($waiting_order)){
                    foreach ($waiting_order as $value){
                        if(self::resolveWaitingOrder($value)){
                            return 6;
                        }
                    }
                }
                break;
            case 4: // 霸王餐
                // 查询当前用户是否有未关闭的相同业务和数量的订单
                $waiting_order = DB::table('laifei_orders')
                    ->where('we_id','=',$this->we_id)
                    ->where('type','=',4)
                    ->where('num','=',$this->num)
                    ->whereIn('status',Data::$laifeiOrderPrepay)
                    ->get()
                    ->toArray();
                $waiting_order = json_decode(json_encode($waiting_order), true);
                // 如果有未支付完成的订单，逐个处理
                if(count($waiting_order)){
                    foreach ($waiting_order as $value){
                        if(self::resolveWaitingOrder($value)){
                            return 7;
                        }
                    }
                }
                break;
            default:
                return false;
        }

        // 拼接订单编号
        $today = date('Ymd');
        $prefix = env("WECHAT_PAYMENT_PREFIX"); // 订单编号前缀，用于区分测试和生产
        $last_trade_no = DB::table('laifei_orders')
            ->where('created_at', '>=', date('Y-m-d ').'00:00:00')
            ->latest()
            ->value('trade_no');
        $last_trade_no = $last_trade_no ?? $prefix.$today.'000000';
        if($last_trade_no === $today.'999999'){
            return 1;
        }
        $trade_no = strval(intval($last_trade_no) + 1);

        // 创建系统订单
        $order_id = DB::table('laifei_orders')->insertGetId([
            'we_id' => $this->we_id,
            'trade_no' => $trade_no,
            'type' => $this->type,
            'outer_id' => $order_message['outer_id'],
            'num'=> $this->num,
            'total_fee' => $order_message['price'],
        ]);

        return [
            'body' => $order_message['title'] . '-' . $order_message['subtitle'],
            'out_trade_no' => $trade_no,
            'total_fee' => $order_message['price'],
            'order_id' => $order_id,
        ];

    }

    /**
     * 生成预付单
     * @param array $message
     * @return string 预付单id
     */
    public function createWechatOrder($message)
    {
        $unify = [
            'body' => $message['body'],
            'out_trade_no' => $message['out_trade_no'],
            'total_fee' => (int)((float)$message['total_fee'] * 100),
            'notify_url' => env('APP_URL').'/api/wechat/pay/success', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $this->openid,
        ];
        // easywechat 支付实例
        $app = Wechat::payment();
        // 创建微信订单:生成预付单
        $prepay_order = $app->order->unify($unify);
//        Log::info('test',$prepay_order);
        // 保存预订单id
        DB::table('laifei_orders')
            ->where('order_id','=', $message['order_id'])
            ->update(['prepay_id' => $prepay_order['prepay_id']]);
        return $prepay_order['prepay_id'];
    }

    /**
     * 返回sdk支付参数
     * @param string $prepay_id 预付单id
     * @return mixed
     */
    public static function sdkConfig($prepay_id)
    {
        $app = Wechat::payment();
        return $app->jssdk->sdkConfig($prepay_id);
    }

    /**
     * 处理未支付完成的订单
     * @param $waiting_order array 待处理订单信息（laifei_orders整行数据）
     * @param bool $close_unsuccess_order 如果订单未支付成功，是否关闭本地订单
     * @return bool true:订单已完成 false:订单已关闭|订单未完成
     */
    public static function resolveWaitingOrder($waiting_order,$close_unsuccess_order = true)
    {
        $app = Wechat::payment();
        $order_status = $app->order->queryByOutTradeNumber($waiting_order['trade_no']);
        if($order_status['trade_state'] === 'SUCCESS'){ //如果旧订单已经支付，那么继续支付完成的操作
            WechatPaySuccessController::paySuccess($waiting_order);
            return true;
        } elseif($close_unsuccess_order) { // 如果没有支付成功，关闭系统内的订单
            DB::table('laifei_orders')
                ->where('order_id','=',$waiting_order['order_id'])
                ->update([
                    'status' => Data::DATA_DB_LAIFEI_ORDERS_STATUS_CLOSE,
                ]);
        }
        return false;
    }

}
